#include "mainwindow.h"
#include <iostream>
#include "ui_mainwindow.h"
#include <QFontDatabase>
#include <QMessageBox>
#include <QInputDialog>
#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFileDialog>
#include <QFontDialog>
#include <QMimeData>
#include <QTextCodec>
#include <QScrollBar>
#include <QMediaPlaylist>
#include <QTextCursor>
#include <QSplashScreen>
#include <QPushButton>
#include <QPrinter>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    upDateOptions();
    ui->setupUi(this);
    c = new Color(this);
    find = new FindAndReplace(this,ui->markdown);
    replace = new Replace(this,ui->markdown);
    //this->setStyleSheet("#MainWindow{background-color:rgba(255,255,255,0);}");
    this->setAutoFillBackground(false);
    ui->markdown->setAcceptRichText(false);
    //ui->Preview->setZoomFactor(2);
    if(imgPath.isEmpty()){
        this->setStyleSheet(QString(""));
        QPalette pl = ui->markdown->palette();
        pl.setBrush(QPalette::Base,Qt::white);
        ui->markdown->setPalette(pl);
        this->setStyleSheet(QString("#MainWindow{background-image:url(114514);background-position:top left;}"));
    }else{
        this->setStyleSheet(QString(""));
        QPalette pl = ui->markdown->palette();
        pl.setBrush(QPalette::Base,Qt::transparent);
        ui->markdown->setPalette(pl);
        this->setStyleSheet(QString("#MainWindow{background-image:url(%1);background-position:top left;}").arg(imgPath));
    }
    ui->markdown->setTabStopWidth(4 * QFontMetrics(ui->markdown->font()).width(" "));
    high = new highlight(ui->markdown->fontPointSize(),ui->markdown->document());
    setWindowTitle(name);
    setWindowIcon(QIcon(":/new/renders/res/logo.ico"));
    ui->actionSave_s->setShortcut(QKeySequence::Save);
    ui->actionFind_F->setShortcut(QKeySequence::Find);
    ui->actionReplace_H->setShortcut(QKeySequence::Replace);
    connect(ui->actionReplace_H,&QAction::triggered,this,&MainWindow::showReplace);
    connect(ui->actioncolor_C,&QAction::triggered,this,&MainWindow::refreshHigh);
    connect(ui->markdown,&QTextEdit::cursorPositionChanged,this,&MainWindow::highLightLine);
    connect(ui->actionHTML_H,&QAction::triggered,this,&MainWindow::toHTML);
    connect(ui->markdown->document(),&QTextDocument::modificationChanged,ui->actionSave_s,&QAction::setEnabled);
    connect(ui->actionPDF_P,&QAction::triggered,this,&MainWindow::toPDF);
    connect(ui->markdown->document(),&QTextDocument::contentsChanged,this,&MainWindow::sendText);
    connect(ui->actionSave_s,&QAction::triggered,this,&MainWindow::sendText);
    connect(ui->actionNew_n,&QAction::triggered,this,&MainWindow::newFile);
    connect(ui->actionSave_s,&QAction::triggered,this,&MainWindow::saveFile);
    connect(ui->actionSaveAs_a,&QAction::triggered,this,&MainWindow::saveAs);
    connect(ui->actionOpen,&QAction::triggered,this,&MainWindow::openFile);
    connect(ui->actionfont,&QAction::triggered,this,&MainWindow::setFont);
    connect(ui->actionCSS,&QAction::triggered,this,&MainWindow::configCss);
    connect(ui->actionHighPlugin_G,&QAction::triggered,this,&MainWindow::configHlCommand);
    connect(ui->actionCode_O,&QAction::triggered,this,&MainWindow::setCode);
    connect(ui->actionwhoAreme_W,&QAction::triggered,this,&MainWindow::setName);
    connect(ui->actionExit_q,&QAction::triggered,this,&MainWindow::exit);
    connect(ui->actionback,&QAction::triggered,this,&MainWindow::setBackgroundImag);
    connect(ui->actionFind_F,&QAction::triggered,this,&MainWindow::showFind);
}

void MainWindow::showFind(){
    find->show();
}

void MainWindow::showReplace()
{
    replace->show();
}

void MainWindow::findNext(){
    QString str = findLineEdit->text();
    if (!ui->markdown->find(str))
    {
        QMessageBox::warning(this, tr("查找"),
                             tr("找不到呀😯").arg(str));
    }
}

void MainWindow::findPre(){
    QString str = findLineEdit->text();
    if (!ui->markdown->find(str, QTextDocument::FindBackward))
    {
        QMessageBox::warning(this, tr("查找"),
                             tr("找不到呀😯").arg(str));
    }
}

void MainWindow::refreshHigh(){
    QMessageBox::warning(nullptr,tr("说明"),tr("编辑之后如果已保存则高亮文件自动改变，还原的话把highlight.gh删掉再重启程序即可哦🧐"));
    c->exec();
    high->init(ui->markdown->fontPointSize());
    double scro = ui->markdown->verticalScrollBar()->value();
    ui->markdown->setPlainText(ui->markdown->toPlainText());
    ui->markdown->verticalScrollBar()->setValue(scro);
}

void MainWindow::setBackgroundImag(){
    imgPath = QFileDialog::getOpenFileName(this,"选择背景图片","","png,jpg(*.png *.jpg)");
    cout << imgPath.toStdString() << endl;
    if(imgPath.isEmpty()){
        this->setStyleSheet(QString(""));
        QPalette pl = ui->markdown->palette();
        pl.setBrush(QPalette::Base,Qt::white);
        ui->markdown->setPalette(pl);
        this->setStyleSheet(QString("#MainWindow{background-image:url(114514);background-position:top left;}"));
    }else{
        this->setStyleSheet(QString(""));
        QPalette pl = ui->markdown->palette();
        pl.setBrush(QPalette::Base,Qt::transparent);
        ui->markdown->setPalette(pl);
        this->setStyleSheet(QString("#MainWindow{background-image:url(\"%1\");background-position:top left;}").arg(imgPath));
    }
}

void MainWindow::highLightLine(){
    QList<QTextEdit::ExtraSelection> extraSelections;

    if (!ui->markdown->isReadOnly()) {
        QTextEdit::ExtraSelection selection;
        QColor lineColor = QColor(Qt::lightGray).lighter(115);
        selection.format.setBackground(lineColor);
        selection.format.setProperty(QTextFormat::FullWidthSelection, true);
        selection.cursor = ui->markdown->textCursor();
        selection.cursor.clearSelection();
        extraSelections.append(selection);
    }
    ui->markdown->setExtraSelections(extraSelections);
}

void MainWindow::toPDF(){

    QString place = QFileDialog::getExistingDirectory(this,tr("%1帮你把pdf导出到你选择的文件夹😀!").arg(name),"");
    qDebug() << place;
    QString realName;
    if(fileName.isEmpty()){
        realName = "Readme.pdf";
    }else{
        realName = fileName.split(".")[0]+".pdf";
    }
    cout << realName.toStdString() << endl;
    ui->Preview->page()->printToPdf(QString("%1/%2").arg(place,realName),QPageLayout(QPageSize(QPageSize::A3),QPageLayout::Portrait,QMarginsF()));
}

void MainWindow::toHTML(){
    bool a;
    QString place = QFileDialog::getExistingDirectory(this,tr("%1帮你把html导出到你选择的文件夹😀!").arg(name),"");
    qDebug() << fileName;
    QString realName;
    if(fileName.isEmpty()){
        realName = "Readme.html";
    }else{
        realName = fileName.split(".")[0]+".html";
    }
    cout << realName.toStdString() << endl;
    QFile f(place+"\\"+realName);
    if (!f.open(QIODevice::WriteOnly | QIODevice::Text))  {
        QMessageBox::warning(this, windowTitle(),
                             tr("无法写入文件 %1: %2").arg(
                                 QDir::toNativeSeparators(place+"\\"+realName), "写不进去"));
        return;
    }
    QTextStream str(&f);
    str.setCodec(QTextCodec::codecForName("UTF-8"));
    str << QString::fromStdString(html);
}

void MainWindow::setOptions(const string &cssPath, const string &highlightCommand, bool codeOpen,const string& name)
{
    ofstream o("Options.op", ios::trunc);
    o << (resPath.isNull() ? this->resPath.toStdString() : cssPath) << '\n'
      << (highlightCommand.empty() ? this->highlightCommand.toStdString() : highlightCommand) << '\n'
      << codeOpen << '\n' << name << "\n";
    o.close();
    upDateOptions();
}

void MainWindow::setName(){
    bool ok;
    QString nm = QInputDialog::getText(this,tr("我是谁？"),"",QLineEdit::EchoMode::Normal,name,&ok);
    if(!nm.isEmpty()){
        name = nm;
    }
    setOptions(resPath.toStdString(),highlightCommand.toStdString(),isCode,name.toStdString());
}

void MainWindow::upDateOptions()
{
    ifstream f("Options.op");
    if (f.good())
    {
        stringstream buf;
        buf << f.rdbuf();
        string res,hlc,nm;
        getline(buf, res);
        getline(buf, hlc);
        resPath = QString::fromStdString(res);
        highlightCommand = QString::fromStdString(hlc);
        string test;
        getline(buf, test);
        isCode = test == "1";
        getline(buf,nm);
        name = QString::fromStdString(nm);
        f.close();
    }
    else
    {
        ofstream o("Options.op", ios::trunc);
        o << resPath.toStdString() << '\n'
          << highlightCommand.toStdString() << '\n'
          << isCode << '\n'
          << name.toStdString() << '\n';
        o.close();
    }
}

void MainWindow::setCode(){
    isCode = !isCode;
    sendText();
}

MainWindow::~MainWindow()
{
    delete ui;
}

bool MainWindow::isModified(){
    return ui->markdown->document()->isModified();
}

void MainWindow::Parse(){
    std::cout << "Parse!" << std::endl;
}

void MainWindow::sendText(){
    //cout << "send" << endl;
    html = QString("<!doctype html>\n<html>\n<head><link rel=\"stylesheet\" type=\"text/css\" href=\"Css.css\">\n\n<script src=\"highlight.js\"></script><script>" + highlightCommand+ "</script>"
                                                                                                                                                                                       "<title>"\
                   + (fileName.isNull()?fileName:fileName.split(".")[0])
                   + "</title></head>").toStdString();
    Parser p(Lexer("").outPut(),isCode);
    p.smallParse(ui->markdown->toPlainText().toStdString(),&html);
    html += "</body></html>";
    //cout << "sent" << endl;
    ui->Preview->setHtml(QString::fromStdString(html),filepath);
    //cout << "sent" <<endl;
    ui->markdown->setFocus();
    //ui->Preview->setZoomFactor(2);
}

void MainWindow::newFile(){
    if (isModified()) {
        QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(), tr("你输入的内容尚未保存，真的要丢弃并新建吗?"));
        if (button != QMessageBox::Yes)
            return;
    }
    filepath.clear();
    ui->markdown->clear();
    ui->markdown->document()->setModified(false);
    ui->actionSave_s->setEnabled(false);
    setWindowTitle(name);
    sendText();
}

void MainWindow::fileOpen(const QString &path){
    QFile f(path);
    if(!f.open(QIODevice::ReadOnly)){
        QMessageBox::warning(this, windowTitle(),
                             tr("打不开文件 %1: %2").arg(
                                 QDir::toNativeSeparators(path), "打不开"));
    }
    filepath = path;
    ui->markdown->setPlainText(QString::fromUtf8(f.readAll()));
    ui->markdown->moveCursor(QTextCursor::End);
    QString cspath = QFileInfo(filepath).absolutePath();
    cout << cspath.toStdString() << endl;
    setOptions(resPath.toStdString(),highlightCommand.toStdString(),isCode,name.toStdString());
    QFile::copy(resPath+"Css.css",cspath+"/Css.css");
    QFile::copy(resPath+"highlight.js",cspath+"/highlight.js");
    sendText();
}

void MainWindow::openFile(){
    if (isModified()) {
        QMessageBox::StandardButton button = QMessageBox::question(this, windowTitle(),
                                                                   tr("你有未保存的修改，要丢弃吗？"));
        if (button != QMessageBox::Yes)
            return;
    }

    QString path = QFileDialog::getOpenFileName(this,
                                                tr("打开Markdown文件"), "", tr("MarkDown File (*.md)"));
    if (path.isEmpty())
        return;
    QFileInfo info(path);
    fileName = info.fileName();
    fileOpen(path);
    setWindowTitle(tr("%1 : %2 %3").arg(name).arg(path).arg("打开了！"));
}

void MainWindow::dragEnterEvent(QDragEnterEvent *e){
    e->acceptProposedAction();
}

void MainWindow::dropEvent(QDropEvent *e){
    QList<QUrl> urls = e->mimeData()->urls();
    if(urls.isEmpty())
        return ;

    QString fileName = urls.first().toLocalFile();
    if(fileName.isEmpty())
        return;

    fileOpen(fileName);
    setWindowTitle(tr("%1 : %2 %3").arg(name).arg(fileName).arg("打开了！"));
}
void MainWindow::configHlCommand(){
    QMessageBox::StandardButton button = QMessageBox::question(this,windowTitle(),tr("此设置不是很容易改对，一不小心高亮就不工作了哦😅，真的要改吗？"));
    if(button != QMessageBox::Yes){
        return;
    }
    bool ok;
    QString temp = QInputDialog::getText(this,tr("js语句"),"",QLineEdit::EchoMode::Normal,highlightCommand,&ok);
    if(ok){
        highlightCommand = temp;
        sendText();
        setOptions(resPath.toStdString(),highlightCommand.toStdString(),isCode,name.toStdString());
    }
}

void MainWindow::saveFile(){
    if (filepath.isEmpty()) {
        saveAs();
        return;
    }

    QFile f(filepath);
    if (!f.open(QIODevice::WriteOnly | QIODevice::Text))  {
        QMessageBox::warning(this, windowTitle(),
                             tr("无法写入文件 %1: %2").arg(
                                 QDir::toNativeSeparators(filepath), "写不进去"));
        return;
    }
    QTextStream str(&f);
    str.setCodec(QTextCodec::codecForName("UTF-8"));
    str << ui->markdown->toPlainText();
    ui->markdown->document()->setModified(false);
}

void MainWindow::saveAs(){
    QString path = QFileDialog::getSaveFileName(this,
                                                tr("保存Markdown文件"), "", tr("MarkDown File (*.md)"));
    if (path.isEmpty())
        return;
    filepath = path;
    saveFile();
}

void MainWindow::exit(){
    ui->markdown->clear();
    ui->Preview->setHtml("");
    filepath.clear();
    fileName.clear();
    setWindowTitle(name);
}

void MainWindow::configCss(){
    QString RPath = QFileDialog::getExistingDirectory(this,tr("选择资源文件夹，在文件夹中放入CSS文件和js文件，并分别命名为Css.css和highlight.js"),"",QFileDialog::Option::ShowDirsOnly);
    //cout << resPath.toStdString() << endl;
    if (RPath.isNull())return;
#ifdef _WINDOWS_
    resPath = RPath + "\\";
#else
    resPath = RPath + "/";
#endif
    QString path = QFileInfo(filepath).absolutePath();
    cout << path.toStdString() << endl;
    setOptions(resPath.toStdString(),highlightCommand.toStdString(),isCode,name.toStdString());
//    QFile::copy(resPath+"Css.css",path+"/Css.css");
//    QFile::copy(resPath+"highlight.js",path+"/highlight.js");
    sendText();
}

void MainWindow::setFont(){
    bool ok = false;
    QFont ft = QFontDialog::getFont(&ok,ui->markdown->font(),this,QString("字体选择"));
    if(ok){
        ui->markdown->setFont(ft);
    }
}

